<?php

namespace ASW\Communication\Rdc;


use ArrayObject;

class RdcClientRequest extends RdcFrame implements \JsonSerializable
{
    private static int $baseSeq = 0;

    public static array $baseProps = [
        'code_lang' => 'php',
        'php'       => [
            'php_version'    => PHP_VERSION,
            'php_version_id' => PHP_VERSION_ID,
            'php_sapi'       => PHP_SAPI,
            'php_os_family'  => PHP_OS_FAMILY,
            'php_os'         => PHP_OS,
            'php_int_size'   => PHP_INT_SIZE,
            'php_is_x64'     => PHP_INT_SIZE === 8
        ],
    ];

    public static function create(string $action, array $args = null): static
    {
        $instance         = new static();
        $instance->seq    = static::$baseSeq++;
        $instance->action = $action;
        $instance->args   = $args === null ? new ArrayObject() : new ArrayObject($args);
        return $instance;
    }

    public static function fromArray(array $array): static
    {
        $instance                   = new static();
        $instance->seq              = $array['seq'] ?? 0;
        $instance->action           = $array['action'] ?? '';
        $instance->args             = new ArrayObject($array['args'] ?? []);
        $instance->settingBehaviors = [];

        $props           = $array['props'] ?? [];
        $instance->props = new ArrayObject($props);

        if (array_key_exists('behaviors', $props) && is_array($props['behaviors'])) {
            foreach ($props['behaviors'] as $behaviorsCode) {
                $instance->settingBehaviors[$behaviorsCode] = 1;
            }
        }
        return $instance;
    }

    private array $settingBehaviors = [];

    public string $action = '';

    public ArrayObject $args;

    public ArrayObject $props;

    private function __construct()
    {
        $this->args  = new ArrayObject();
        $this->props = new ArrayObject(static::$baseProps);
    }

    /**
     * 设置行为
     * @param RdcClientRequestBehavior $behavior
     * @param bool $enabled
     * @return void
     */
    public function setBehavior(RdcClientRequestBehavior $behavior, bool $enabled = true): void
    {
        if ($enabled) {
            $this->settingBehaviors[$behavior->value] = 1;
        } else {
            unset($this->settingBehaviors[$behavior->value]);
        }
    }

    /**
     * 是否包含指定的行为
     * @param RdcClientRequestBehavior $behavior
     * @return bool
     */
    public function hasBehavior(RdcClientRequestBehavior $behavior): bool
    {
        return array_key_exists($behavior->value, $this->settingBehaviors);
    }

    public function jsonSerialize(): static
    {
        $this->props["behaviors"]           = array_keys($this->settingBehaviors);
        $this->props['sdk_version']         = '0.0.1';
        $this->props['serialize_timestamp'] = time();
        return $this;
    }
}